1. 定性判断算法的效率
(1)时间复杂度:算法运行后对时间需求量的定性描述(数据结构课程集中讨论的内容)
(2)空间复杂度:算法运行后对空间需求量的定性描述(判断方法类似于时间复杂度)
2. 大O表示法
(1)算法效率严重依赖于操作(Operation)数量
(2)操作数量的估算可以作为时间复杂度的估算
(3)在判断时首先关注操作数量的最高次项
O(5) =O(1)
O(2n+1)=O(2n)=O(n)
O(n2+n+1) = O(n2)
O(3n3+1)=O(3n3)=O(n3)
3. 常见时间复杂度
(1)线性阶时间复杂度:O(n)
for(int i=0;i<n; i++){ //这里是一些复杂度为O(1)的程序语句 }
(2)对数阶时间复杂度:O(logn)
int i = 1; //循环次数为2^x = n,即x = log2n。 //忽略底数后,时间复杂度为logn while (i<n){ i *= 2; //复杂度为O(1)的程序语句 }
(3)平方阶时间复杂度:O(n2)
//循环总次数:n2 for(int i=0; i<n; i++){ for(int j=0; j<n; j++){ //复杂度为O(1)的程序语句 } }
【计算练习1】
//循环总次数:n + (n-1) + (n-2) +...+ 1 = (n+1)*n/2 ==>O(n2) for(int i=0; i<n; i++){ for(int j=i; j<n; j++){ //注意j从i(而不是1)开始。 //复杂度为O(1)的程序语句 } }
【计算练习2】求func函数的时间复杂度
void t(int n) ==>O(n) { int i=0; while(i < n){ cout << i << endl; } } void func(int n) //n*(n+1) ==>O(n2) { int i= 0; while(i < n){ t(n); //O(n) i++; //O(1) } }
【计算练习3】求test函数的时间复杂度
void t(int n) ==>O(n) { int i=0; while(i < n){ cout << i << endl; } } //时间复杂度为:O(n) + O(n2) + O(n3) ==>O(n3) void test(int n) { t(n); //O(n) //O(n2) for(int i=0; i<n; i++) t(i); //O(n3) for(int i=0; i<n; i++) for(int j=i; j<n; j++) t(i); //O(n) }
4. 小结
(1)时间复杂度是算法运行时对于时间的需求量
(2)大O表示法用于描述算法的时间复杂度
(3)大O表示法只关注操作数量的最高次项
(4)常见的时间复杂度为:线性阶、平方阶和对数阶